home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1987, 1988 Stanley T. Shebs, University of Utah. */
- /* This program may be used, copied, modified, and redistributed freely */
- /* for noncommercial purposes, so long as this notice remains intact. */
-
- #pragma comment(exestr, "@(#) help.c 12.1 95/05/09 ")
-
- /* RCS $Header: help.c,v 1.1 88/06/21 12:30:12 shebs Exp $ */
-
- /* This file is devoted to commands and other functions related specifically */
- /* to help. Almost all of the xconq help code is here. */
-
- /* At least in X, the help window covers most of the xconq display, so */
- /* total redraws are necessary. This can be slow - fix would be to do */
- /* per-window redrawing only as need, and place help window to cover as few */
- /* of the other windows as possible (especially world map). */
-
- #include "config.h"
- #include "misc.h"
- #include "period.h"
- #include "side.h"
- #include "unit.h"
- #include "map.h"
-
- extern int helpwinlines;
-
- /* Display the news file on stdout if it exists, be silent if it doesn't. */
- /* (Used only during program startup.) */
-
- maybe_dump_news()
- {
- FILE *fp;
-
- make_pathname(XCONQLIB, NEWSFILE, "", spbuf);
- if ((fp = fopen(spbuf, "r")) != NULL) {
- while (fgets(spbuf, BUFSIZE-1, fp) != NULL) {
- fputs(spbuf, stdout);
- }
- fclose(fp);
- }
- }
-
- /* The general help command. It first lists the available commands, */
- /* then a legend to map display, then the current news about xconq, then */
- /* details about the period/units. Player can page screens back and forth, */
- /* which explains some odd index adjusts at bottom of loop. */
-
- x_help(side)
- Side *side;
- {
- int i = side->reqvalue2;
- char opt = side->reqch;
-
- init_wprintf(side, NULL);
- switch (opt) {
- case ' ':
- case 'n':
- if (i < 4+period.numutypes) i++;
- break;
- case '-':
- if (i > 0) i--;
- break;
- case '\014':
- break; /* redraw */
- default:
- conceal_help(side);
- /*redraw(side);*/
- return;
- }
- switch (i) {
- case 0:
- command_help(side);
- break;
- case 1:
- legend_help(side);
- break;
- case 2:
- make_pathname(XCONQLIB, NEWSFILE, "", spbuf);
- if (!show_file(side, spbuf)) {
- wprintf(side, "No news is good news.");
- }
- break;
- case 3:
- describe_mapfiles(side);
- break;
- case 4:
- describe_period(side);
- break;
- default:
- /* i guaranteed to be in right range */
- describe_utype(side, i - 5);
- break;
- }
- ask_help_char(side);
- request_input(side, NULL, x_help);
- side->reqvalue2 = i;
- }
-
- /* The command proper must request a character for whether to go to next */
- /* or previous screen, or to quit entirely. */
-
- do_help(side, n)
- Side *side;
- int n;
- {
- if (reveal_help(side)) {
- init_wprintf(side, NULL);
- command_help(side);
- ask_help_char(side);
- request_input(side, NULL, x_help);
- side->reqvalue2 = 0;
- }
- }
-
- /* Prompt for a char from help window. */
-
- ask_help_char(side)
- Side *side;
- {
- char *help = "[Space bar to continue, '-' for prev, all else quits]";
-
- draw_fg_text(side, side->help, 0, (helpwinlines-1)*side->fh, help);
- }
-
- /* Generate a legend for all the various symbols and pictures. */
- /* (Does not include cursor box or tiny side numbers.) */
-
- legend_help(side)
- Side *side;
- {
- int t, u, tcol = 2 * side->margin + side->hw;
- int spacing = side->hh + 4 * side->margin;
- int offset = side->hh/4, second = 30*side->fw;
-
- /* first column of things is constant for all periods */
- draw_blast_icon(side, side->help,
- side->margin, 0*spacing, 'b', side->enemycolor);
- draw_fg_text(side, side->help, tcol, 0*spacing+offset, "miss");
- draw_blast_icon(side, side->help,
- side->margin, 1*spacing, 'c', side->enemycolor);
- draw_fg_text(side, side->help, tcol, 1*spacing+offset, "hit");
- draw_blast_icon(side, side->help,
- side->margin, 2*spacing, 'd', side->enemycolor);
- draw_fg_text(side, side->help, tcol, 2*spacing+offset, "kill");
- for_all_terrain_types(t) {
- char ch;
- switch(side->showmode) {
- case FULLHEX:
- case BOTHICONS:
- ch = HEX;
- break;
- case BORDERHEX:
- ch = OHEX;
- break;
- case TERRICONS:
- ch = ttypes[t].tchar;
- break;
- }
- draw_hex_icon(side, side->help,
- side->margin, (t+3)*spacing,
- (side->monochrome ? side->fgcolor : side->hexcolor[t]),
- (side->monochrome ? ttypes[t].tchar : ch));
- draw_fg_text(side, side->help,
- tcol, (t+3)*spacing+offset, ttypes[t].name);
- }
- for_all_unit_types(u) {
- draw_unit_icon(side, side->help,
- second, u*spacing, u, side->fgcolor);
- draw_fg_text(side, side->help,
- second+tcol, u*spacing+offset, utypes[u].name);
- }
- }
-
- /* This command provides a short note about the current hex. It is */
- /* useful as a supplement to the general help command. */
-
- do_ident(side, n)
- Side *side;
- int n;
- {
- char view = side_view(side, side->curx, side->cury);
- char t = terrain_at(side->curx, side->cury);
- Side *side2;
-
- if (view == UNSEEN) {
- notify(side, "You see unexplored territory");
- } else if (view == EMPTY) {
- notify(side, "You see unoccupied %s", ttypes[t].name);
- } else {
- side2 = side_n(vside(view));
- notify(side, "You see a %s %s (in the %s)",
- (side2 == NULL ? "neutral" : side2->name),
- utypes[vtype(view)].name, ttypes[t].name);
- }
- }
-
- /* Dump out the characteristics of a single unit type. This works by */
- /* jumping into the help loop, so all the other types can be looked at also. */
-
- x_unit_info(side)
- Side *side;
- {
- int u;
-
- if ((u = find_unit_char(side->reqch)) >= 0) {
- if (u != NOTHING) {
- if (reveal_help(side)) {
- init_wprintf(side, NULL);
- describe_utype(side, u);
- ask_help_char(side);
- request_input(side, NULL, x_help);
- side->reqvalue2 = u;
- }
- }
- clear_prompt(side);
- } else {
- request_input(side, NULL, x_unit_info);
- }
- }
-
- /* The command proper just prompts and issues the request. */
-
- do_unit_info(side, n)
- Side *side;
- int n;
- {
- ask_unit_type(side, "Details on which unit type?", NULL);
- request_input(side, NULL, x_unit_info);
- }
-
- /* Spit out all the general period parameters in a readable fashion. */
-
- describe_period(side)
- Side *side;
- {
- int u, r, t, i;
-
- wprintf(side, "This period is named \"%s\".", period.name);
- wprintf(side, "");
- wprintf(side,
- "It includes %d unit types, %d resource types, and %d terrain types.",
- period.numutypes, period.numrtypes, period.numttypes);
- wprintf(side, "First unit type is %s, first product type is %s.",
- (period.firstutype == NOTHING ? "none" :
- utypes[period.firstutype].name),
- (period.firstptype == NOTHING ? "none" :
- utypes[period.firstptype].name));
- wprintf(side, "");
- wprintf(side,
- "Countries are %d hexes across, between %d and %d hexes apart.",
- period.countrysize, period.mindistance, period.maxdistance);
- wprintf(side, "Known area is %d hexes across.", period.knownradius);
- wprintf(side, "Default scale is %d km/hex.", period.scale);
- if (period.allseen)
- wprintf(side, "All units are always seen by all sides.");
- wprintf(side, "");
- if (period.counterattack)
- wprintf(side, "Defender always gets a counter-attack.");
- else
- wprintf(side, "Defender does not get a counter-attack.");
- wprintf(side, "Neutral units add %d%% to defense, hit over %d is a nuke.",
- period.neutrality, period.nukehit);
- if (period.efficiency > 0)
- wprintf(side, "Unit recycling is %d%% efficient.", period.efficiency);
- wprintf(side, "");
- for_all_terrain_types(t) {
- wprintf(side, "Terrain: %c %s (%s)",
- ttypes[t].tchar, ttypes[t].name, ttypes[t].color);
- }
- wprintf(side, "");
- for_all_resource_types(r) {
- wprintf(side, "Resource: %c %s (%s)",
- ' ', rtypes[r].name, rtypes[r].help);
- }
- wprintf(side, "");
- for_all_unit_types(u) {
- wprintf(side, "Unit: %c %s (%s)",
- utypes[u].uchar, utypes[u].name, utypes[u].help);
- }
- wprintf(side, "");
- if (period.notes != NULL) {
- for (i = 0; period.notes[i] != NULL; ++i) {
- wprintf(side, "%s", period.notes[i]);
- }
- }
- }
-
- /* Full details on the given type of unit. This may be used either for */
- /* online help or for building a descriptive file. The icon will only */
- /* show up for online help, otherwise the display calls have no effect. */
-
- describe_utype(side, u)
- Side *side;
- int u;
- {
- int r, t, u2;
-
- wprintf(side, " '%c' %s (territory value %d)",
- utypes[u].uchar, utypes[u].name, utypes[u].territory);
- wprintf(side, " %s", utypes[u].help);
- if (utypes[u].bitmapname != NULL)
- wprintf(side, " bitmap \"%s\"", utypes[u].bitmapname);
- else
- wprintf(side, "");
- draw_hex_icon(side, side->help, side->margin, side->margin,
- side->fgcolor, HEX);
- draw_unit_icon(side, side->help, side->margin, side->margin,
- u, side->bgcolor);
- wprintf(side, "Init: %d in country, %d/10000 hexes density, %s.",
- utypes[u].incountry, utypes[u].density,
- (utypes[u].named ? "named" : "unnamed"));
- wprintf(side, "Maximum speed %d hexes/turn, %d%% under control. %s %s",
- utypes[u].speed, utypes[u].control,
- (utypes[u].onemove ? "(auto)" : ""),
- (utypes[u].jumpmove ? "(jumps)" : ""));
- wprintf(side, "%d HP, crippled at %d HP, chance to retreat %d%%.",
- utypes[u].hp, utypes[u].crippled, utypes[u].retreat);
- wprintf(side, "%d%% extra for start up, %d%% extra for R&D.",
- utypes[u].startup, utypes[u].research);
- wprintf(side, "%d extra moves used up by an attack.",
- utypes[u].hittime);
- wprintf(side,
- "%d%% to succumb to siege, %d%% to revolt, attrition damage %d HP.",
- utypes[u].siege, utypes[u].revolt, utypes[u].attdamage);
- if (utypes[u].seerange == 1) {
- wprintf(side, "Chance to see others %d%%.", utypes[u].seebest);
- } else {
- wprintf(side, "Chance to see %d%% at 1 hex, to %d%% at %d hexes.",
- utypes[u].seebest, utypes[u].seeworst, utypes[u].seerange);
- }
- wprintf(side, "Own visibility is %d.", utypes[u].visibility);
- if (utypes[u].volume > 0 || utypes[u].holdvolume > 0)
- wprintf(side, "Volume is %d, volume of hold is %d.",
- utypes[u].volume, utypes[u].holdvolume);
- wprintf(side, "%s %s",
- (utypes[u].changeside ? "Can be made to change sides." : ""),
- (utypes[u].disband ? "Can be disbanded and sent home." : ""));
- wprintf(side, "%s %s",
- (utypes[u].maker ? "Builds units all the time." : ""),
- (utypes[u].selfdestruct ? "Hits by self-destruction." : ""));
- wprintf(side, "");
- wprintf(side, "%s",
- " Resource ToBui Prod Store Eats ToMov Hits HitBy");
- wprintf(side, "%s",
- " (0) (0) (0) (0) (0) (0) (0)");
- for_all_resource_types(r) {
- sprintf(spbuf, "%10s: ", rtypes[r].name);
- append_number(spbuf, utypes[u].tomake[r], 0);
- append_number(spbuf, utypes[u].produce[r], 0);
- append_number(spbuf, utypes[u].storage[r], 0);
- append_number(spbuf, utypes[u].consume[r], 0);
- append_number(spbuf, utypes[u].tomove[r], 0);
- append_number(spbuf, utypes[u].hitswith[r], 0);
- append_number(spbuf, utypes[u].hitby[r], 0);
- wprintf(side, "%s", spbuf);
- }
- wprintf(side, "");
- wprintf(side, "%s",
- " Terrain Slowed Rand% Hide% Defn% Prod% Attr% Acdn%");
- wprintf(side, "%s",
- " (-) (0) (0) (0) (0) (0) (0)");
- for_all_terrain_types(t) {
- sprintf(spbuf, "%10s: ", ttypes[t].name);
- append_number(spbuf, utypes[u].moves[t], -1);
- append_number(spbuf, utypes[u].randommove[t], 0);
- append_number(spbuf, utypes[u].conceal[t], 0);
- append_number(spbuf, utypes[u].defense[t], 0);
- append_number(spbuf, utypes[u].productivity[t], 0);
- append_number(spbuf, utypes[u].attrition[t], 0);
- append_number(spbuf, utypes[u].accident[t], 0);
- wprintf(side, "%s", spbuf);
- }
- wprintf(side, "");
- wprintf(side, "%s%s",
- " Hit% Damg Cap% Guard Pro%",
- " Holds Enter Leave Mob% Bridg Build Fix");
- wprintf(side, "%s%s",
- " (0) (0) (0) (0) (0)",
- " (0) (1) (0) (100) (0) (0) (0)");
- for_all_unit_types(u2) {
- sprintf(spbuf, "%c: ", utypes[u2].uchar);
- append_number(spbuf, utypes[u].hit[u2], 0);
- append_number(spbuf, utypes[u].damage[u2], 0);
- append_number(spbuf, utypes[u].capture[u2], 0);
- append_number(spbuf, utypes[u].guard[u2], 0);
- append_number(spbuf, utypes[u].protect[u2], 0);
- append_number(spbuf, utypes[u].capacity[u2], 0);
- append_number(spbuf, utypes[u].entertime[u2], 1);
- append_number(spbuf, utypes[u].leavetime[u2], 0);
- append_number(spbuf, utypes[u].mobility[u2], 100);
- append_number(spbuf, utypes[u].bridge[u2], 0);
- append_number(spbuf, utypes[u].make[u2], 0);
- append_number(spbuf, utypes[u].repair[u2], 0);
- wprintf(side, "%s", spbuf);
- }
- wprintf(side, "");
- }
-
- /* A simple table-printing utility. Blanks out default values so they don't */
- /* clutter the table. */
-
- append_number(buf, value, dflt)
- char *buf;
- int value, dflt;
- {
- if (value != dflt) {
- sprintf(tmpbuf, "%5d ", value);
- strcat(buf, tmpbuf);
- } else {
- strcat(buf, " ");
- }
- }
-
- /* Dump assorted information into files, so they can be studied at leisure, */
- /* or by people with screens too small for online help. */
-
- do_printables(side, n)
- Side *side;
- int n;
- {
- int u;
-
- init_wprintf(side, CMDFILE);
- command_help(side);
- finish_wprintf();
- notify(side, "Dumped commands to \"%s\".", CMDFILE);
- init_wprintf(side, PARMSFILE);
- describe_period(side);
- for_all_unit_types(u) {
- wprintf(side, "--------------------------------------------------");
- wprintf(side, "");
- describe_utype(side, u);
- wprintf(side, "");
- }
- finish_wprintf();
- notify(side, "Dumped period data to \"%s\".", PARMSFILE);
- dump_view(side);
- notify(side, "Dumped current view to \"%s\".", VIEWFILE);
- }
-
- /* Put the current view into a file. */
-
- dump_view(side)
- Side *side;
- {
- char ch1, ch2;
- int x, y, i, view, vs;
- Side *side2;
- FILE *fp;
-
- if ((fp = fopen(VIEWFILE, "w")) != NULL) {
- for (y = world.height-1; y >= 0; --y) {
- for (i = 0; i < y; ++i) fputc(' ', fp);
- for (x = 0; x < world.width; ++x) {
- view = side_view(side, x, y);
- if (view == UNSEEN) {
- ch1 = ch2 = ' ';
- } else if (view == EMPTY) {
- ch1 = ttypes[terrain_at(x, y)].tchar;
- ch2 = (side->showmode == BORDERHEX ? ' ' : ch1);
- } else {
- ch1 = utypes[vtype(view)].uchar;
- vs = vside(view);
- side2 = side_n(vside(view));
- ch2 = (side2 ? ((side == side2) ? ' ' : vs + '0') : '`');
- }
- fputc(ch1, fp);
- fputc(ch2, fp);
- }
- fprintf(fp, "\n");
- }
- } else {
- notify(side, "Can't open \"%s\"!!", VIEWFILE);
- }
- }
-
- /* This kicks in on a unit type prompt. Just give barest details, rely */
- /* on general help for full unit descriptions. This could be spiffier */
- /* and use the help window, but getting the interaction right is just too */
- /* hard... */
-
- help_unit_type(side)
- Side *side;
- {
- int u;
-
- for_all_unit_types(u) {
- if (side->bvec[u]) {
- notify(side, " %c %s; %s",
- utypes[u].uchar, utypes[u].name, utypes[u].help);
- }
- }
- }
-